﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Security.Cryptography;

namespace VoizeRemoteCore
{
    public class Connection
    {


        public Connection(string ip, string port,string user,string password)
        {

            if (this.Auth(user, password, ip, port) == true)
            {
                m_IP = ip;
                m_Port = port;

                this.Connect();
            }
            else
            {
                throw new Exception("Authentication failed.");
            }
        }



        private NetworkStream m_Stream;
        private TcpClient m_Client;
        private string m_IP;
        private string m_Port;



        private bool Auth(string user, string password, string ip, string port)
        {
            bool retval = false;

            TcpClient client = new TcpClient();
            IPEndPoint end_point_ip = new IPEndPoint(IPAddress.Parse(ip), Int32.Parse(port));
            NetworkStream stream;
            ASCIIEncoding encoder = new ASCIIEncoding();
            byte[] buffer;
            byte[] response_buffer = new byte[256];
            string message;
            Byte[] OriginalBytes;
            Byte[] EncodedBytes;
            string hash;
            MD5CryptoServiceProvider md5;

            OriginalBytes = ASCIIEncoding.Default.GetBytes(password);
            md5 = new MD5CryptoServiceProvider();
            EncodedBytes = md5.ComputeHash(OriginalBytes);
            hash = BitConverter.ToString(EncodedBytes);

            client.Connect(end_point_ip);
            stream = client.GetStream();

            buffer = encoder.GetBytes("auth;"+user+";"+hash);

            stream.Write(buffer, 0, buffer.Length);
            stream.Flush();
            stream.Read(response_buffer, 0, response_buffer.Length);
            message = encoder.GetString(response_buffer, 0, response_buffer.Length);

            if (message.StartsWith("ok"))
                retval = true;

            client.Close();

            return retval;
        }


        public bool IsConnected
        {
            get { return m_Client.Connected; }
        }



        private bool Connect()
        {
            try
            {
                IPEndPoint end_point_ip;

                m_Client = new TcpClient();
                end_point_ip = new IPEndPoint(IPAddress.Parse(m_IP), Int32.Parse(m_Port));

                m_Client.Connect(end_point_ip);
                m_Stream = m_Client.GetStream();

                return true;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
                //return false;
            }

        }


        public void ImportSound()
        {
            throw new NotImplementedException();
        }


        private void List()
        {
            ASCIIEncoding encoder = new ASCIIEncoding();
            byte[] buffer = encoder.GetBytes("list");
            byte[] response_buffer = new byte[256];
            int count = 0;

            m_Stream.Write(buffer, 0, buffer.Length);
            m_Stream.Flush();

            while ((count = m_Stream.Read(response_buffer, 0, response_buffer.Length)) != 0)
            {
                Console.WriteLine(encoder.GetString(response_buffer, 0, response_buffer.Length));
                if (response_buffer.Length >= 256)
                {
                    response_buffer = null;
                    response_buffer = new byte[256];
                }
                if (m_Stream.DataAvailable == false)
                    break;
            }
        }

        /// <summary>
        /// Supported commands: list play pause next previous stop help
        /// </summary>
        /// <param name="command"></param>
        public string SendCommand(string command)
        {
            if (m_Client.Connected)
            {
                if (command == "list")
                {
                    this.List();
                    return "List ok";
                }
                else
                {
                    ASCIIEncoding encoder = new ASCIIEncoding();
                    byte[] buffer = encoder.GetBytes(command);
                    byte[] response_buffer = new byte[150];
                    string message;

                    m_Stream.Write(buffer, 0, buffer.Length);
                    m_Stream.Flush();
                    m_Stream.Read(response_buffer, 0, response_buffer.Length);
                    message = encoder.GetString(response_buffer, 0, response_buffer.Length);
                    //Console.WriteLine("\n");
                    //Console.Write("\t\tAction ok: ");
                    //Console.WriteLine(message, 0, message.Length);
                    return "\t\tAction ok: " + message;
                }
            }
            else
            {
                return "\t\tDisconnected.";
            }
        }
    }
}
